package com.douqu.game.core.entity.world.map;

import com.bean.core.buffer.ByteBuffer;
import com.bean.core.util.Utils;
import com.douqu.game.core.config.FunctionConfig;
import com.douqu.game.core.config.StableDataConfig;
import com.douqu.game.core.config.map.CityConfig;
import com.douqu.game.core.config.map.CityDropConfig;
import com.douqu.game.core.config.map.CityDropGroupConfig;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.e.E_ActionPlayerType;
import com.douqu.game.core.e.E_CityDropBelong_Status;
import com.douqu.game.core.e.E_CityInOutType;
import com.douqu.game.core.e.E_StableDataType;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.common.TwoTuple;
import com.douqu.game.core.entity.ext.data.BaseData;
import com.douqu.game.core.factory.ConfigFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.factory.FunctionFactory;
import com.douqu.game.core.factory.WorldInfoFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGMainProto;
import com.douqu.game.core.protobuf.SGMapProto;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.MapUtils;
import com.douqu.game.core.util.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import static com.douqu.game.core.e.E_CityDropPower_Type.*;

/**
 * @Author: Bean
 * @Description:
 * @Date: 2018-04-16 10:59
 */
public class WorldMapData extends BaseData
{
    /**
     * 不为空表示属于是单人战场的主人
     */
    private String masterPlayerIndex;
    /**
     * 平均等级，用来重新刷驻军
     */
    private int playerAverageLevel;

    /**
     * 当前这一次等级刷新的时间
     */
    private int curFlushTimeHourCount;
    /**
     * 下一次刷新时间索引
     */
    private int nextFlushTimeIndex;


    /** 最小等级，平均等级最小不能小这个值 */
    private int minPlayerAverageLevel;

    private Map<Integer, CityBean> cityMap = new ConcurrentHashMap<>();

    /**
     * 行动对象所在的城
     */
    private Map<String, Integer> spriteBeanCityMap = new ConcurrentHashMap<>();

    /**
     * 匹配组
     */
    private List<MapMatchTeam> matchTeamList = new CopyOnWriteArrayList<>();

    /** 结盟的阵营 */
    private int[] allyCampAry = new int[0];

    /**
     * 驻军的ID增量
     */
    private int createArmyId;


    /**
     * 缓存正在查看城的玩家
     */
    private Map<String, Integer> lookCityPlayerMap = new ConcurrentHashMap<>();



    public WorldMapData(String masterPlayerIndex)
    {
        FunctionConfig functionConfig = DataFactory.getInstance().getGameObject(DataFactory.FUNCTION_KEY, FunctionFactory.INTO_WORLD_MAP);
        if(functionConfig != null)
            minPlayerAverageLevel = functionConfig.lv;

        this.masterPlayerIndex = masterPlayerIndex;
    }

    @Override
    public void init()
    {
        cityMap.clear();

        List<CityConfig> list = DataFactory.getInstance().getDataList(DataFactory.CITY_KEY);
        if(list != null)
        {
            for(CityConfig cityConfig : list)
            {
                cityMap.put(cityConfig.id, new CityBean(cityConfig.id, cityConfig.camp, masterPlayerIndex));
            }
        }

    }

    @Override
    public void checkInit()
    {
        if(cityMap.isEmpty())
        {
            init();
        }
    }

    @Override
    public void reset() {

    }

    @Override
    public void checkReset() {

    }

    @Override
    public void writeTo(ByteBuffer buffer)
    {
        buffer.writeShort(cityMap.size());
        for(CityBean cityBean : cityMap.values())
        {
            cityBean.writeTo(buffer);
        }
    }

    @Override
    public void loadFrom(ByteBuffer buffer)
    {
        int size = buffer.readShort();

        CityBean cityBean = null;
        cityMap.clear();
        for(int i = 0; i < size; i++)
        {
            cityBean = new CityBean(masterPlayerIndex);
            cityBean.loadFrom(buffer);
            cityMap.put(cityBean.id, cityBean);
        }
    }

    public void checkInitGarrison()
    {
        for(CityBean cityBean : cityMap.values())
        {
            if(cityBean.getSpriteGarrisonList().isEmpty())
            {
                cityBean.initGarrison();
            }
        }
    }

    public void update(long currentTime, WorldMapUpdateResult updateResult)
    {
        for(CityBean cityBean : cityMap.values())
        {
            cityBean.update(updateResult);
        }

        for(MapMatchTeam matchTeam : matchTeamList)
        {
            if(matchTeam.isStartBattle())
            {
                LogUtils.debug("可以开始战斗了 -> " + matchTeam);

                updateResult.addStartBattleMatchTeam(matchTeam);

                matchTeamList.remove(matchTeam);
            }
            else if(matchTeam.isOverdue())
            {
                LogUtils.info("大地图匹配组超时,恢复初始状态 -> " + matchTeam);
                matchTeam.destroy();
                matchTeamList.remove(matchTeam);
            }
        }
    }

    /**
     * 刷新驻军
     */
    public void initGarrison()
    {
        for(CityBean cityBean : cityMap.values())
        {
            cityBean.initGarrison();
        }
    }

    /**
     * 是否结盟
     * @param myCamp
     * @param targetCamp
     * @return
     */
    public boolean isAlly(int myCamp, int targetCamp)
    {
        if(myCamp == targetCamp)
            return true;

        boolean myResult = false, targetResult = false;
        for(int camp : allyCampAry)
        {
            if(camp == myCamp)
                myResult = true;

            if(camp == targetCamp)
                targetResult = true;
        }
        return myResult && targetResult;
    }

    public void removeSprite(SpriteBean spriteBean, CityBean cityBean, boolean removeLook, E_CityInOutType type)
    {
        if(cityBean == null)
            cityBean = getCurCity(spriteBean);
        if(cityBean != null)
            cityBean.removeSprite(spriteBean, type);

        removeSpriteCurCity(spriteBean.getObjectIndex());

        if(removeLook)
            lookCityPlayerMap.remove(spriteBean.getObjectIndex());
    }


    /**
     * 玩家离线
     * @param player
     */
    public void playerOffline(Player player)
    {
        SpritePlayerBean spritePlayerBean = getPlayerActionBean(player.getObjectIndex());

        LogUtils.debug("玩家离线，设置大地图中为离线玩家 -> player:" + player.getName() + " -> " + spritePlayerBean);

        if(spritePlayerBean != null)
        {
            spritePlayerBean.setActionPlayerType(E_ActionPlayerType.OFFLINE, DataFactory.currentTime);
            spritePlayerBean.setPlayerController(null);
            spritePlayerBean.setInCity(false);
            spritePlayerBean.setPlayer(player);

            checkPlayer(spritePlayerBean);

            //退出大地图时,检测一下是否应该切换到世界地图了
            if(!WorldInfoFactory.getInstance().isSingleWorldMapByLv(player))
            {
                //已经应该切换到世界地图了
                WorldInfoFactory.getInstance().removeSingleWorldMap(player.getObjectIndex());
            }
        }

        removeLookCity(player.getObjectIndex());
    }

    public void checkPlayer(SpritePlayerBean spritePlayerBean)
    {

    }

    /**
     * 玩家上线
     * @param playerController
     */
    public  void playerOnline(PlayerController playerController)
    {
        SpritePlayerBean spritePlayerBean = getPlayerActionBean(playerController.getObjectIndex());
        if(spritePlayerBean != null)
        {
            spritePlayerBean.setActionPlayerType(E_ActionPlayerType.ONLINE, 0);
            spritePlayerBean.setPlayerController(playerController);
        }
    }

    public CityBean getCurCity(SpriteBean spriteBean)
    {
        Integer value = getSpriteCurCity(spriteBean.getObjectIndex());
        if(value != null)
            return getCity(value.intValue());

        return null;
    }

    public SpritePlayerBean initActionBean(E_ActionPlayerType type, PlayerController playerController, boolean initCard)
    {
        CityConfig city = DataFactory.getInstance().getMainCityByCamp(playerController.getPlayer().camp);
        if(initCard) playerController.getPlayer().getWorldMapTaskData().setBattleCardList(playerController.getPlayer().getCardData().getBattleCardList());

        SpritePlayerBean spritePlayerBean = new SpritePlayerBean(type, playerController.getPlayer(), city.id, masterPlayerIndex);

        backMainCity(spritePlayerBean, SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_FREE, false);

        return spritePlayerBean;
    }

    public void backMainCity(SpriteBean spriteBean, SGCommonProto.E_ARMY_STATUS status, boolean leaveCurCity)
    {
        if(spriteBean instanceof SpritePlayerBean)
        {
            if(leaveCurCity)
            {
                CityBean curCity = getCurCity(spriteBean);
                if(curCity != null)
                {
                    curCity.leave(spriteBean, null, E_CityInOutType.OUT_BACK_MAIN);
                }
            }

            CityConfig cityConfig = DataFactory.getInstance().getMainCityByCamp(spriteBean.camp);
            CityBean cityBean = getCity(cityConfig.getId());
            cityBean.arrive(spriteBean, true, E_CityInOutType.IN_BACK_MAIN);
            setSpriteCurCity(spriteBean.getObjectIndex(), cityConfig.id);
            spriteBean.setStatus(status);

            // 回城要将复活次数和使用道具的次数清空
//            Player player = ((SpritePlayerBean) spriteBean).getPlayer();
//            if(player!= null){
//                player.getExtInfo(SettingInfo.class).getAutoRecover().clearItemTimes();
//            }

            SGMapProto.S2C_MapInfoAfterBattle.Builder response = SGMapProto.S2C_MapInfoAfterBattle.newBuilder();
            response.setCurCity(cityConfig.id);
            LogUtils.debug("--------" + response);
            spriteBean.sendMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_MapInfoAfterBattle_VALUE, response.build().toByteArray());
        }
    }

    /** 大地图城市掉落 ************************************/
    public void cityDrop(CityDropGroupConfig groupConfig,SGCommonProto.E_CAMP_TYPE campType,String index){
        if (groupConfig == null){
            LogUtils.error("WorldMap drop error groupConfig is null ");
            return;
        }
        List<CityBean> changeList = null;
        synchronized (cityMap) {
            /**
             * 1.根据 groupConfig取到cityDrop集合
             */
            Map<Integer, List<CityDropConfig>> cityDropConfigMap = null;
            /**
             * 2.根据刷新势力 与 奖励的drop获取要得到的城市
             * 如果来源是玩家或者阵营触发 一定存在阵营 根据刷新地区的权重获取可刷新城市
             * 如果是归属于全局的 由系统发放的 则由全部城市随机取
             */
            if (groupConfig.visibleType != E_CityDropBelong_Status.CITY_DROP_ALL.getCode()) {
                 if (campType == null) {
                    //这里一定要有阵营
                    LogUtils.error("worldMap cityDrop error camp is null groupConfig.visibleType -> " + groupConfig.visibleType);
                    return;
                }
                if (groupConfig.visibleType == E_CityDropBelong_Status.CITY_DROP_PERSON.getCode() && StringUtils.isNullOrEmpty(index)) {
                    LogUtils.error("worldMap cityDrop error playerIndex is null groupConfig.visibleType -> " + groupConfig.visibleType);
                    return;
                }
                if (groupConfig.visibleType == E_CityDropBelong_Status.CITY_DROP_POWER.getCode() && StringUtils.isNullOrEmpty(index)){
                    index = String.valueOf(campType.getNumber());
                }
                //归属势力归属个人一定从我方城里拿
                Map<Integer,Integer> canDropCityWeight = getCampWeightCity(campType.getNumber());
                cityDropConfigMap = MapUtils.getCityDropMap(groupConfig,canDropCityWeight);
                Set<Integer> weightList = cityDropConfigMap.keySet();
                Map<Integer, List<CityBean>> cityBeanMap = getCityBeanMapByMap(groupConfig, campType, weightList, index);
                changeList = MapUtils.getCanUseCity(cityDropConfigMap, cityBeanMap, groupConfig, campType, index);
            } else {
                //全部玩家归属可见 所有城随机城市发放奖励
                cityDropConfigMap = MapUtils.getCityDropMap(groupConfig);
                changeList = MapUtils.getCanUseCity(cityDropConfigMap, cityMap, groupConfig);
            }
        }
        //通知玩家变化城市掉落
        SGMapProto.S2C_HegemonyCityDrop.Builder response = MapUtils.getSendCityDropResponse(changeList,groupConfig,campType,index);
        try {
            sendCityDropMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_HegemonyCityDrop_VALUE,response.build().toByteArray(),E_CityDropBelong_Status.getStatus(groupConfig.visibleType),groupConfig,index);
        }catch (Exception e){
            e.printStackTrace();
            LogUtils.errorException(e);
        }
    }

    public Map<Integer ,Integer> getCampWeightCity(int camp){
        Map<Integer,Integer> map = new HashMap<>();
        CityConfig cityConfig = null;
        for (Map.Entry<Integer,CityBean> entry:cityMap.entrySet()){
            if (entry.getValue().camp == camp){
                cityConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_KEY,entry.getKey());
                if (cityConfig != null){
                    int weight = cityConfig.getAreaWeight(camp);
                    map.merge(weight,1,(v1,v2) -> v1 + v2);
                }
            }
        }
        return map;
    }

    /**
     * 根据阵营权重分类所有可以分配奖励的城市
     * @param groupConfig
     * @param campType
     * @param weightList
     * @return
     */
    public Map<Integer, List<CityBean>> getCityBeanMapByMap(CityDropGroupConfig groupConfig,SGCommonProto.E_CAMP_TYPE campType,Set<Integer> weightList,String index){
        Map<Integer, List<CityBean>> cityBeanMap = new HashMap<>();
        List<CityBean> cityBeanList = null;
        CityConfig cityConfig = null;
        int weight = 0;
        boolean flag = false;
        CityDropBean dropBean = null;
        CityDropGroupConfig cityDropGroupConfig = null;
        for (CityBean bean:cityMap.values()){
            //如果是主城不刷任何奖励 屏蔽掉
            if (bean.getConfig().type == SGCommonProto.E_CITY_TYPE.CITY_TYPE_CAPITAL_VALUE){
                continue;
            }
            flag = false;
            if (groupConfig.visibleType != E_CityDropBelong_Status.CITY_DROP_ALL.getCode()){
                if (groupConfig.locateType == E_CITY_DROP_POWER_OWN.getCode()){
                    //己方
                    if (bean.camp == campType.getNumber()){
                        flag = true;
                    }
                } else if (groupConfig.locateType == E_CITY_DROP_POWER_ENEMY.getCode()){
                    //奖励刷在敌方
                    if (bean.camp != campType.getNumber()){
                        flag = true;
                    }
                }else if (groupConfig.locateType == E_CITY_DROP_POWER_ALL.getCode()){
                    //奖励刷在全地图
                    flag = true;
                }
                if (flag){
                    if(groupConfig.visibleType == E_CityDropBelong_Status.CITY_DROP_PERSON.getCode()){
                        //归属个人
                        dropBean = bean.getCityDropData().getPlayerDropMap().get(index);
                    }else{
                        dropBean = bean.getCityDropData().getCampDropMap().get(campType.getNumber());
                    }
                    //没有奖励 或者奖励为0 或者过期可以触发奖励
                    if (dropBean == null || dropBean.getDropGroup() == 0
                            || (cityDropGroupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP,dropBean.getDropGroup())) == null
                            || MapUtils.getSeconds(dropBean.getDropTime() + MapUtils.keepTime(cityDropGroupConfig.aliveTime)) <= 0){
                        cityConfig = bean.getConfig();
                        weight = cityConfig.getAreaWeight(campType.getNumber());
                        if (weightList.contains(weight)){
                            //如果这个城市符合奖励类型
                            if ((cityBeanList = cityBeanMap.get(weight)) == null){
                                cityBeanList = new ArrayList<>();
                                cityBeanMap.put(weight,cityBeanList);
                            }
                            cityBeanList.add(bean);
                        }
                    }
                }
            }
        }
        return cityBeanMap;
    }

    /**
     * 得到奖励
     * @param
     * @return
     */
    public TwoTuple<CityDropBean,Integer> getDropReward(CityBean cityBean,PlayerController playerController){
        TwoTuple<CityDropBean,Integer> twoTuple = new TwoTuple();
        CityDropBean cityDropBean = null;
        E_CityDropBelong_Status status = null;
        twoTuple.setFirst(null);
        if (cityBean == null){
            return twoTuple;
        }
        /**
         * 先判断当前玩家领取的奖励 世界 > 阵营 > 个人
         */
        CityDropData cityDropData = cityBean.getCityDropData();
        CityDropGroupConfig groupConfig = null;

        //世界
        if ((cityDropBean = cityDropData.getAllDrop()) != null
                && (groupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, cityDropBean.getDropGroup())) != null
                && MapUtils.getSeconds(cityDropBean.getDropTime() + MapUtils.keepTime(groupConfig.aliveTime)) > 0){
            status = E_CityDropBelong_Status.CITY_DROP_ALL;
        }
        //阵营
        if (status == null){
            if ((cityDropBean = cityDropData.getCampDropMap().get(playerController.getPlayer().camp)) != null
                    && (groupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, cityDropBean.getDropGroup())) != null
                    && MapUtils.getSeconds(cityDropBean.getDropTime() + MapUtils.keepTime(groupConfig.aliveTime)) > 0){
                status = E_CityDropBelong_Status.CITY_DROP_POWER;
            }
        }
        //个人
        if (status == null){
            if ((cityDropBean = cityDropData.getPlayerDropMap().get(playerController.getObjectIndex())) != null
                    && (groupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, cityDropBean.getDropGroup())) != null
                    && MapUtils.getSeconds(cityDropBean.getDropTime() + MapUtils.keepTime(groupConfig.aliveTime)) > 0){
                status = E_CityDropBelong_Status.CITY_DROP_PERSON;
            }
            //remove掉这个对象
            cityDropData.getPlayerDropMap().remove(playerController.getObjectIndex());
        }
        if (status == null){
            LogUtils.debug("cityDrop don't have drop cityId -> " + cityBean.id + " player -> " + playerController.getName());
            return twoTuple;
        }

        twoTuple.setFirst(cityDropBean);
        twoTuple.setSecond(cityDropBean.getRewardId());
        //通知受到影响的相关玩家
        /**
         * 如果领走的是世界级 判断是否有阵营的奖励 有的话通知相关的玩家
         * 如果没有阵营的判断是否有玩家级别的掉落奖励 有的话通知玩家没有的话不推送
         * 如果阵营奖励有的阵营 或者 玩家奖励有的玩家没有 则有的推送有未执行完的奖励 没有的推送结束
         */
        SGMapProto.S2C_HegemonyCityDrop.Builder response;
        SGCommonProto.CityDrop.Builder cityDrop;
        int remainTime = 0;
        List<SpritePlayerBean> playerBeanList;
        CityDropBean cityDropBean1;
        try {
            if (status == E_CityDropBelong_Status.CITY_DROP_ALL){
                for (Map.Entry<Integer,CityDropBean> entry:cityDropData.getCampDropMap().entrySet()){
                    if ((groupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, entry.getValue().getDropGroup())) != null
                            && (remainTime = MapUtils.getSeconds(entry.getValue().getDropTime() + MapUtils.keepTime(groupConfig.aliveTime))) > 0){
                        //这个城有阵营奖励 通知这个阵营的玩家
                        response = SGMapProto.S2C_HegemonyCityDrop.newBuilder();
                        cityDrop = SGCommonProto.CityDrop.newBuilder();
                        cityDrop.setCityId(cityBean.id);
                        cityDrop.setConfigId(entry.getValue().getRewardId());
                        cityDrop.setRemainTime(remainTime * MapUtils.ONT_SECOND);
                        response.addDropList(cityDrop);
                        sendCityDropMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_HegemonyCityDrop_VALUE,response.build().toByteArray(),E_CityDropBelong_Status.CITY_DROP_POWER,null,String.valueOf(playerController.getPlayer().camp));
                    }else{
                        //这里只处理与当前循环一致阵营的玩家
                        playerBeanList =  getSpriteBeanOnline(entry.getKey());
                        //遍历所有玩家这个城没有阵营奖励判断每个玩家的个人奖励 进行通知
                        for (SpritePlayerBean playerBean:playerBeanList){
                            if ((cityDropBean1 = cityDropData.getPlayerDropMap().get(playerBean.getObjectIndex())) != null && (groupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, cityDropBean1.getDropGroup())) != null
                                    && (remainTime = MapUtils.getSeconds(cityDropBean1.getDropTime() + MapUtils.keepTime(groupConfig.aliveTime))) > 0){
                                response = SGMapProto.S2C_HegemonyCityDrop.newBuilder();
                                cityDrop = SGCommonProto.CityDrop.newBuilder();
                                cityDrop.setCityId(cityBean.id);
                                cityDrop.setConfigId(cityDropBean1.getRewardId());
                                cityDrop.setRemainTime(remainTime * MapUtils.ONT_SECOND);
                                response.addDropList(cityDrop);
                                sendCityDropMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_HegemonyCityDrop_VALUE,response.build().toByteArray(),E_CityDropBelong_Status.CITY_DROP_PERSON,null,playerBean.getObjectIndex());
                            }else{
                                //如果对于这个玩家 既没有阵营奖励 也 没有个人掉落奖励 通知清空
                                response = SGMapProto.S2C_HegemonyCityDrop.newBuilder();
                                cityDrop = SGCommonProto.CityDrop.newBuilder();
                                cityDrop.setCityId(cityBean.id);
                                cityDrop.setConfigId(0);
                                cityDrop.setRemainTime(0);
                                response.addDropList(cityDrop);
                                sendCityDropMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_HegemonyCityDrop_VALUE,response.build().toByteArray(),E_CityDropBelong_Status.CITY_DROP_PERSON,null,playerBean.getObjectIndex());
                            }
                        }
                    }
                }
            }else if (status == E_CityDropBelong_Status.CITY_DROP_POWER){
                //如果领取的是阵营奖励 判断通知同一阵营的玩家是否有该奖励
                playerBeanList =  getSpriteBeanOnline(playerController.getPlayer().camp);
                for (SpritePlayerBean playerBean:playerBeanList){
                    //这里只处理和领奖玩家同一阵营的玩家
                    if ((cityDropBean1 = cityDropData.getPlayerDropMap().get(playerBean.getObjectIndex())) != null && (groupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, cityDropBean1.getDropGroup())) != null
                            && (remainTime = MapUtils.getSeconds(cityDropBean1.getDropTime() + MapUtils.keepTime(groupConfig.aliveTime))) > 0){
                        response = SGMapProto.S2C_HegemonyCityDrop.newBuilder();
                        cityDrop = SGCommonProto.CityDrop.newBuilder();
                        cityDrop.setCityId(cityBean.id);
                        cityDrop.setConfigId(cityDropBean1.getRewardId());
                        cityDrop.setRemainTime(remainTime * MapUtils.ONT_SECOND);
                        response.addDropList(cityDrop);
                        sendCityDropMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_HegemonyCityDrop_VALUE,response.build().toByteArray(),E_CityDropBelong_Status.CITY_DROP_PERSON,null,playerBean.getObjectIndex());
                    }else{
                        //如果对于这个玩家 既没有阵营奖励 也 没有个人掉落奖励 通知清空
                        response = SGMapProto.S2C_HegemonyCityDrop.newBuilder();
                        cityDrop = SGCommonProto.CityDrop.newBuilder();
                        cityDrop.setCityId(cityBean.id);
                        cityDrop.setConfigId(0);
                        cityDrop.setRemainTime(0);
                        response.addDropList(cityDrop);
                        sendCityDropMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_HegemonyCityDrop_VALUE,response.build().toByteArray(),E_CityDropBelong_Status.CITY_DROP_PERSON,null,playerBean.getObjectIndex());
                    }
                }
            }else{
                //如果玩家领取的个人奖励 通知玩家奖励消失
                response = SGMapProto.S2C_HegemonyCityDrop.newBuilder();
                cityDrop = SGCommonProto.CityDrop.newBuilder();
                cityDrop.setCityId(cityBean.id);
                cityDrop.setConfigId(0);
                cityDrop.setRemainTime(0);
                response.addDropList(cityDrop);
                sendCityDropMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_HegemonyCityDrop_VALUE,response.build().toByteArray(),E_CityDropBelong_Status.CITY_DROP_PERSON,null,playerController.getObjectIndex());
            }
        }catch (Exception e){
            LogUtils.errorException(e);
        }

        return twoTuple;
    }

    /**
     * 玩家进入大地图获取初始化城市掉落信息
     * @param player
     * @return
     */
    public List<SGCommonProto.CityDrop> initMyDropCityInfo(Player player){
        List<SGCommonProto.CityDrop> dropList = new ArrayList<>();
        //遍历所有城
        CityDropBean cityDropBean = null;
        CityDropGroupConfig groupConfig = null;
        CityDropData cityDropData = null;
        SGCommonProto.CityDrop.Builder cityDrop;
        int remainTime = 0;
        for (CityBean cityBean:cityMap.values()){
            cityDropData = cityBean.getCityDropData();
            /**
             * 这里的cityDrop 初始化不能封装
             * 因为如果执行其他的if方法 会改变需要参数的值
             */
            //如果有世界级的城市掉落 则显示世界级的
            if ((cityDropBean = cityDropData.getAllDrop()) != null
                    && (groupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, cityDropBean.getDropGroup())) != null
                    && (remainTime = MapUtils.getSeconds(cityDropBean.getDropTime() + MapUtils.keepTime(groupConfig.aliveTime))) > 0){
                cityDrop = SGCommonProto.CityDrop.newBuilder();
                cityDrop.setCityId(cityBean.id);
                cityDrop.setConfigId(cityDropBean.getRewardId());
                cityDrop.setRemainTime(remainTime * MapUtils.ONT_SECOND);
                dropList.add(cityDrop.build());
                continue;
            }
            //如果有同阵营的城市掉落 则显示阵营级的掉落
            if ((cityDropBean = cityDropData.getCampDropMap().get(player.camp)) != null
                    && (groupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, cityDropBean.getDropGroup())) != null
                    && (remainTime = MapUtils.getSeconds(cityDropBean.getDropTime() + MapUtils.keepTime(groupConfig.aliveTime))) > 0){
                cityDrop = SGCommonProto.CityDrop.newBuilder();
                cityDrop.setCityId(cityBean.id);
                cityDrop.setConfigId(cityDropBean.getRewardId());
                cityDrop.setRemainTime(remainTime * MapUtils.ONT_SECOND);
                dropList.add(cityDrop.build());
                continue;
            }
            if ((cityDropBean = cityDropData.getPlayerDropMap().get(player.getObjectIndex())) != null
                    && (groupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, cityDropBean.getDropGroup())) != null
                    && (remainTime = MapUtils.getSeconds(cityDropBean.getDropTime() + MapUtils.keepTime(groupConfig.aliveTime))) > 0){
                cityDrop = SGCommonProto.CityDrop.newBuilder();
                cityDrop.setCityId(cityBean.id);
                cityDrop.setConfigId(cityDropBean.getRewardId());
                cityDrop.setRemainTime(remainTime * MapUtils.ONT_SECOND);
                dropList.add(cityDrop.build());
            }
        }
        return dropList;
    }

    public Map<Integer,List<CityBean>> getWeightCity(CityDropGroupConfig groupConfig,SGCommonProto.E_CAMP_TYPE campType){
        Map<Integer,List<CityBean>> weightCityMap = new HashMap<>();
        CityConfig cityConfig = null;
        for (CityBean bean:cityMap.values()){
            //如果是主城 不刷道具
            cityConfig = bean.getConfig();
            if (cityConfig.type == SGCommonProto.E_CITY_TYPE.CITY_TYPE_CAPITAL_VALUE){
                continue;
            }
            if (groupConfig.locateType == E_CITY_DROP_POWER_OWN.getCode()){
                if (campType.getNumber() == bean.camp){
                    addCityWeight(weightCityMap,cityConfig,bean,groupConfig.locateType);
                }
            }
            if (groupConfig.locateType == E_CITY_DROP_POWER_ENEMY.getCode()){
                if (campType.getNumber() != bean.camp){
                    addCityWeight(weightCityMap,cityConfig,bean,groupConfig.locateType);
                }
            }
            if (groupConfig.locateType == E_CITY_DROP_POWER_ALL.getCode()){
                addCityWeight(weightCityMap, cityConfig, bean, groupConfig.locateType);
            }
        }
        return weightCityMap;
    }

    public void addCityWeight(Map<Integer,List<CityBean>> weightCityMap,CityConfig cityConfig,CityBean bean,int setting1){
        if (cityConfig != null){
            int weight = cityConfig.getAreaWeight(setting1);
            if (weightCityMap.get(weight) == null){
                weightCityMap.put(weight,new ArrayList<>());
            }
            weightCityMap.get(weight).add(bean);
        }
    }

    public SpritePlayerBean getPlayerActionBean(String playerIndex)
    {
        SpriteBean spriteBean = getSpriteBean(playerIndex);
        if(spriteBean instanceof SpritePlayerBean)
            return (SpritePlayerBean) spriteBean;
        else
            return null;
    }

    public SpriteBean getSpriteBean(String objectIndex)
    {
        Integer cityId = spriteBeanCityMap.get(objectIndex);
        if(cityId != null)
        {
            CityBean cityBean = getCity(cityId);
            return cityBean == null ? null : cityBean.getSpriteBean(objectIndex);
        }
        return null;
    }

    /**
     * 获取大地图全部在线玩家
     * @return
     */
    public List<SpritePlayerBean> getSpriteBeanOnline(int camp){
        List<SpritePlayerBean> spriteBeanList = new ArrayList<>();
        for (CityBean cityBean:cityMap.values()){
            for (SpritePlayerBean playerBean:cityBean.getSpritePlayerList()){
                if (playerBean.getPlayerController() != null && playerBean.camp == camp){
                    spriteBeanList.add(playerBean);
                }
            }
        }
        return spriteBeanList;
    }


    public CityBean getCity(int id)
    {
        return cityMap.get(id);
    }


//    public boolean setCityStatus(int cityId, int status)
//    {
//        CityBean cityBean = getCity(cityId);
//        if(cityBean != null)
//        {
//            cityBean.setStatus(SGCommonProto.E_CITY_STATUS.forNumber(status));
//            return cityBean.getStatus() != null;
//        }
//
//        return false;
//    }

    public List<SGCommonProto.CityItem> parseList()
    {
        List<SGCommonProto.CityItem> list = new ArrayList<>();
        for(CityBean cityBean : cityMap.values())
        {
            list.add(cityBean.parse());
        }
        return list;
    }

    public Map<Integer, CityBean> getCityMap() {
        return cityMap;
    }

    public int getCreateArmyId() {
        return ++createArmyId;
    }

    public void dispatchMsg(int code, byte[] data)
    {
//        LogUtils.debug("全员转发消息 isSingle -> " + isSingle() + "  code -> " + SGMainProto.E_MSG_ID.forNumber(code));
        for(CityBean cityBean : cityMap.values())
        {
            cityBean.dispatchMsg(code, data);
        }
    }

    /**
     * 争霸赛变化通知所有在大地图里的玩家
     * @param flag
     */
    public void sendHegemonyChange(boolean flag){
        LogUtils.info("通知所有玩家争霸赛变化 ->" + flag);
        SGMapProto.S2C_WorldMapIsHegemony.Builder response = SGMapProto.S2C_WorldMapIsHegemony.newBuilder();
        response.setIsHegemony(flag);
        for (CityBean cityBean : cityMap.values()){
            cityBean.sendHegemonyChange(SGMainProto.E_MSG_ID.MsgID_WorldMap_IsHegemony_VALUE,response.build().toByteArray(),flag);
        }
    }


    public void sendCityDropMsg(int code, byte[] data,E_CityDropBelong_Status type,CityDropGroupConfig config,String... playerIndex) throws Exception
    {
        for(CityBean cityBean : cityMap.values())
        {
            cityBean.sendCityDropMsg(code, data, type, config, playerIndex);
        }
    }

    public void dispatchWarn(String key, Object... params)
    {
        for(CityBean cityBean : cityMap.values())
        {
            cityBean.dispatchWarn(key, params);
        }
    }



    public void addMatchTeam(MapMatchTeam mapMatchTeam)
    {
        matchTeamList.add(mapMatchTeam);
    }

//    public void updateMasterPlayerIndex(String playerIndex)
//    {
//        for(CityBean cityBean : cityMap.values())
//        {
//            cityBean.setMasterPlayerIndex(playerIndex);
//        }
//    }

    public void removeLookCity(String playerIndex)
    {
        Integer city = lookCityPlayerMap.get(playerIndex);
        if(city != null)
        {
            getCity(city).removeLookPlayer(playerIndex);
            lookCityPlayerMap.remove(playerIndex);
        }
    }

    public void addLookCity(CityBean cityBean, String playerIndex)
    {
        cityBean.addLookPlayer(playerIndex);
        lookCityPlayerMap.put(playerIndex, cityBean.id);
    }


    public Map<String, Integer> getLookCityPlayerMap()
    {
        return lookCityPlayerMap;
    }

    public void setSpriteCurCity(String objectIndex, int city)
    {
        spriteBeanCityMap.put(objectIndex, city);
    }

    public int getSpriteCurCity(String objectIndex)
    {
        Integer value = spriteBeanCityMap.get(objectIndex);
        return value != null ? value.intValue() : 0;
    }

    public Map<String, Integer> getSpriteBeanCityMap() {
        return spriteBeanCityMap;
    }


    public void removeSpriteCurCity(String objectIndex)
    {
        spriteBeanCityMap.remove(objectIndex);
    }

    public int getPlayerAverageLevel() {
        return playerAverageLevel;
    }

    public void setPlayerAverageLevel(int playerAverageLevel)
    {
        this.playerAverageLevel = playerAverageLevel;
    }

    public int getMinPlayerAverageLevel() {
        return minPlayerAverageLevel;
    }

    //获取争霸赛开始时间
    public int getHegemonyStartTime(StableDataConfig stableDataConfig) {
        if(stableDataConfig == null){
            LogUtils.error("stableDataConfig is null hegemonyStartTime error stableId ->" + E_StableDataType.HEGEMONY_START_END_TIME.getCode());
        }
        return stableDataConfig.stringValue[0];
    }

    //获取争霸赛结束时间
    public int getHegemonyEndTime(StableDataConfig stableDataConfig) {
        if(stableDataConfig == null){
            LogUtils.error("stableDataConfig is null hegemonyEndTime error stableId ->" + E_StableDataType.HEGEMONY_START_END_TIME.getCode());
        }
        return stableDataConfig.stringValue[1];
    }

    public boolean hegemonyIsSettle(){
        int currentHour = CoreUtils.getHour();
        return hegemonyIsSettle(currentHour);
    }

    public boolean hegemonyIsSettle(Player player){
        //判断争霸赛是否开放
        String message = CoreUtils.checkFunctionOpen(FunctionFactory.WORLD_MAP_HEGEMONY,player);
        if (message != null){
            LogUtils.error(message);
            return false;
        }
        return hegemonyIsSettle();
    }

    //判断现在是否在结算时间
    public boolean hegemonyIsSettle(int currentHour){
        StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.HEGEMONY_START_END_TIME.getCode());
        //验证当日时间
        if (currentHour > getHegemonyEndTime(stableDataConfig) || currentHour < getHegemonyStartTime(stableDataConfig)){
            LogUtils.error("worldMap battle error currentHour :" +  currentHour + " start :" + getHegemonyStartTime(stableDataConfig) +
                    " end :" + getHegemonyEndTime(stableDataConfig));
            return false;
        }
        //验证总结算时间
        if (CoreUtils.getWeek() > stableDataConfig.goods[0].type){
            LogUtils.error("worldMap battle error  currentWeek:" + CoreUtils.getWeek() + " week:" + stableDataConfig.goods[0].type);
            return false;
        }else if (CoreUtils.getWeek() == stableDataConfig.goods[0].type){
            //小时
            if (currentHour > stableDataConfig.goods[0].id){
                LogUtils.info("worldMap battle error  currentHour:" + currentHour + " hour:" +  stableDataConfig.goods[0].id);
                return false;
            }else if (currentHour == stableDataConfig.goods[0].id){
                //分钟
                if (CoreUtils.getMinute() > stableDataConfig.goods[0].value){
                    LogUtils.info("worldMap battle error  currentMinute:"  + CoreUtils.getMinute() + " minute:" + stableDataConfig.goods[0].value);
                    return false;
                }
            }
        }
        return true;
    }

    public boolean isSingle() {
        return !Utils.isNullOrEmpty(masterPlayerIndex);
    }


    public boolean checkFlush(int playerLv)
    {
        if(ConfigFactory.WORLD_MAP_FLUSH_TIME == null)
            return true;

        if(nextFlushTimeIndex >= ConfigFactory.WORLD_MAP_FLUSH_TIME.length)
            return false;

        if(++curFlushTimeHourCount == ConfigFactory.WORLD_MAP_FLUSH_TIME[nextFlushTimeIndex])
        {
            this.playerAverageLevel = playerLv;

            curFlushTimeHourCount = 0;
            nextFlushTimeIndex++;

            return true;
        }

        return false;
    }




}
